#include <Ethernet.h>
#include <SPI.h>
boolean reading = false;
boolean flashstate = false;
boolean fadestate = false;
unsigned long flashtimer;
unsigned long fadetimer;
int rval = 0;
int gval = 0;
int bval = 0;
#define red 3
#define green 5
#define blue 6
String inputString = "";         // a string to hold incoming data
boolean stringComplete = false;  // whether the string is complete
String ledcolour = "red";
////////////////////////////////////////////////////////////////////////
//CONFIGURE
////////////////////////////////////////////////////////////////////////
byte ip[] = { 
  10, 0, 0, 45 };   //Manual setup only
byte gateway[] = { 
  10, 0, 0, 2 }; //Manual setup only
byte subnet[] = { 
  255, 255, 255, 0 }; //Manual setup only

// if need to change the MAC address (Very Rare)
byte mac[] = { 
  0xDE, 0xBE, 0xFE, 0xEF, 0xFE, 0xED };

EthernetServer server = EthernetServer(80); //port 80
////////////////////////////////////////////////////////////////////////

void setup(){
  Serial.begin(9600);

  //Pins 10,11,12 & 13 are used by the ethernet shield


  pinMode(red, OUTPUT);
  pinMode(green, OUTPUT);
  pinMode(blue, OUTPUT);

  //Ethernet.begin(mac);
  Ethernet.begin(mac, ip, gateway, subnet); //for manual setup

  server.begin();
  Serial.println(Ethernet.localIP());

}

void loop(){

  // listen for incoming clients, and process qequest.
  checkForClient();
  analogWrite(red,rval);
  analogWrite(green,gval);
  analogWrite(blue,bval);  
  if (flashstate){
    if(millis() > (flashtimer + 1000)) { // 5 mins
      //    Serial.println("Checking Zones");
      flash();
      flashtimer = millis();
    }
  }
  if (fadestate){
    if(millis() > (fadetimer + 500)) { // 5 mins
      //    Serial.println("Checking Zones");
      fadeled();
      fadetimer = millis();
    }
  }
}
void checkForClient(){

  EthernetClient client = server.available();

  if (client) {

    // an http request ends with a blank line
    boolean currentLineIsBlank = true;
    boolean sentHeader = false;

    while (client.connected()) {
      if (client.available()) {

        if(!sentHeader){
          // send a standard http response header
          client.println("HTTP/1.1 200 OK");
          client.println("Content-Type: text/html");
          client.println("Connection: close");  // the connection will be closed after completion of the response          
          client.println();
          sentHeader = true;
        }

        char c = client.read();

        if(reading && c == ' ') reading = false;
        if(c == '?'){
          reading = true; //found the ?, begin reading the info
        }

        if(reading){

          // get the new byte:
          char inChar = c; 
          // add it to the inputString:
          inputString += inChar;
          // if the incoming character is a newline, set a flag
          // so the main loop can do something about it:
          if (inChar == '@') {
            stringComplete = true;
          } 
          if (inChar == '\n') {
            stringComplete = true;
          } 
        }

        if (stringComplete) {     
          int i, count; 
          for (i=0, count=0; inputString[i]; i++) 
            count += (inputString[i] == ','); 

          String newData[count];

          for(int i =0; i < count;i++){
            int firstpos = inputString.indexOf(",");
            newData[i] = inputString.substring(0,firstpos);
            inputString = inputString.substring(firstpos+1,inputString.length());
          }
          inputString = "";
          newData[0].replace("?","");
          if (newData[0] == "stop"){
            client.println("Stopping");
            rval = 0;
            gval = 0;
            bval = 0;
            flashstate = false;
            fadestate = false;
            client.stop();
            break;   
          } 
          else if (newData[0] == "flash"){
            ledcolour = newData[1];
            flashstate = true;
            client.println("Flashing:");
            client.println(newData[1]);
            client.stop();
            break; 
          }
          else if (newData[0] == "fade"){
            fadestate = true;
            client.println("Fading");
            client.stop();
            break; 
          }
          else{
            rval = constrain(convint(newData[0]),0,255);
            gval = constrain(convint(newData[1]),0,255);
            bval = constrain(convint(newData[2]),0,255);          
            client.println("Colour Values:");
            client.println(rval);
            client.println(gval);
            client.println(bval);
            client.stop();
            break;

          }

        }

        if (c == '\n' && currentLineIsBlank)  break;

        if (c == '\n') {
          currentLineIsBlank = true;
        }
        else if (c != '\r') {
          currentLineIsBlank = false;
        }

      }
    }

    delay(1); // give the web browser time to receive the data
    client.stop(); // close the connection:
    inputString = "";
    stringComplete = false;
    //    reading = false;
  } 
 inputString = "";
    stringComplete = false;
}

int convint(String Data){
  char carray2[Data.length() +1];
  Data.toCharArray(carray2,sizeof(carray2));
  return atoi(carray2); 
}

void flash(){
  if (flashstate){

    if (ledcolour == "red"){
      if(rval = 255){
        rval = 0;
      } 
      else{
        rval = 255; 
      }
    }
    if (ledcolour == "green"){
      if(gval = 255){
        gval = 0;
      } 
      else{
        gval = 255; 
      }
    }
    if (ledcolour == "blue"){
      if(bval = 255){
        bval = 0;
      } 
      else{
        bval = 255; 
      }              
    }
  } 
}
int colorpos = 0;
boolean forward = true;
int rgbmatrix[139][3] = {
  {
    128,0,0            }
  ,
  {
    139,0,0            }
  ,
  {
    165,42,42            }
  ,
  {
    178,34,34            }
  ,
  {
    220,20,60            }
  ,
  {
    255,0,0            }
  ,
  {
    255,99,71            }
  ,
  {
    255,127,80            }
  ,
  {
    205,92,92            }
  ,
  {
    240,128,128            }
  ,
  {
    233,150,122            }
  ,
  {
    250,128,114            }
  ,
  {
    255,160,122            }
  ,
  {
    255,69,0            }
  ,
  {
    255,140,0            }
  ,
  {
    255,165,0            }
  ,
  {
    255,215,0            }
  ,
  {
    184,134,11            }
  ,
  {
    218,165,32            }
  ,
  {
    238,232,170            }
  ,
  {
    189,183,107            }
  ,
  {
    240,230,140            }
  ,
  {
    128,128,0            }
  ,
  {
    255,255,0            }
  ,
  {
    154,205,50            }
  ,
  {
    85,107,47            }
  ,
  {
    107,142,35            }
  ,
  {
    124,252,0            }
  ,
  {
    127,255,0            }
  ,
  {
    173,255,47            }
  ,
  {
    0,100,0            }
  ,
  {
    0,128,0            }
  ,
  {
    34,139,34            }
  ,
  {
    0,255,0            }
  ,
  {
    50,205,50            }
  ,
  {
    144,238,144            }
  ,
  {
    152,251,152            }
  ,
  {
    143,188,143            }
  ,
  {
    0,250,154            }
  ,
  {
    0,255,127            }
  ,
  {
    46,139,87            }
  ,
  {
    102,205,170            }
  ,
  {
    60,179,113            }
  ,
  {
    32,178,170            }
  ,
  {
    47,79,79            }
  ,
  {
    0,128,128            }
  ,
  {
    0,139,139            }
  ,
  {
    0,255,255            }
  ,
  {
    0,255,255            }
  ,
  {
    224,255,255            }
  ,
  {
    0,206,209            }
  ,
  {
    64,224,208            }
  ,
  {
    72,209,204            }
  ,
  {
    175,238,238            }
  ,
  {
    127,255,212            }
  ,
  {
    176,224,230            }
  ,
  {
    95,158,160            }
  ,
  {
    70,130,180            }
  ,
  {
    100,149,237            }
  ,
  {
    0,191,255            }
  ,
  {
    30,144,255            }
  ,
  {
    173,216,230            }
  ,
  {
    135,206,235            }
  ,
  {
    135,206,250            }
  ,
  {
    25,25,112            }
  ,
  {
    0,0,128            }
  ,
  {
    0,0,139            }
  ,
  {
    0,0,205            }
  ,
  {
    0,0,255            }
  ,
  {
    65,105,225            }
  ,
  {
    138,43,226            }
  ,
  {
    75,0,130            }
  ,
  {
    72,61,139            }
  ,
  {
    106,90,205            }
  ,
  {
    123,104,238            }
  ,
  {
    147,112,219            }
  ,
  {
    139,0,139            }
  ,
  {
    148,0,211            }
  ,
  {
    153,50,204            }
  ,
  {
    186,85,211            }
  ,
  {
    128,0,128            }
  ,
  {
    216,191,216            }
  ,
  {
    221,160,221            }
  ,
  {
    238,130,238            }
  ,
  {
    255,0,255            }
  ,
  {
    218,112,214            }
  ,
  {
    199,21,133            }
  ,
  {
    219,112,147            }
  ,
  {
    255,20,147            }
  ,
  {
    255,105,180            }
  ,
  {
    255,182,193            }
  ,
  {
    255,192,203            }
  ,
  {
    250,235,215            }
  ,
  {
    245,245,220            }
  ,
  {
    255,228,196            }
  ,
  {
    255,235,205            }
  ,
  {
    245,222,179            }
  ,
  {
    255,248,220            }
  ,
  {
    255,250,205            }
  ,
  {
    250,250,210            }
  ,
  {
    255,255,224            }
  ,
  {
    139,69,19            }
  ,
  {
    160,82,45            }
  ,
  {
    210,105,30            }
  ,
  {
    205,133,63            }
  ,
  {
    244,164,96            }
  ,
  {
    222,184,135            }
  ,
  {
    210,180,140            }
  ,
  {
    188,143,143            }
  ,
  {
    255,228,181            }
  ,
  {
    255,222,173            }
  ,
  {
    255,218,185            }
  ,
  {
    255,228,225            }
  ,
  {
    255,240,245            }
  ,
  {
    250,240,230            }
  ,
  {
    253,245,230            }
  ,
  {
    255,239,213            }
  ,
  {
    255,245,238            }
  ,
  {
    245,255,250            }
  ,
  {
    112,128,144            }
  ,
  {
    119,136,153            }
  ,
  {
    176,196,222            }
  ,
  {
    230,230,250            }
  ,
  {
    255,250,240            }
  ,
  {
    240,248,255            }
  ,
  {
    248,248,255            }
  ,
  {
    240,255,240            }
  ,
  {
    255,255,240            }
  ,
  {
    240,255,255            }
  ,
  {
    255,250,250            }
  ,
  {
    0,0,0            }
  ,
  {
    105,105,105            }
  ,
  {
    128,128,128            }
  ,
  {
    169,169,169            }
  ,
  {
    192,192,192            }
  ,
  {
    211,211,211            }
  ,
  {
    220,220,220            }
  ,
  {
    245,245,245            }
  ,
  {
    255,255,255            }

};

void fadeled(){
  if (fadestate){
    rval = rgbmatrix[colorpos][0];
    gval = rgbmatrix[colorpos][1];
    bval = rgbmatrix[colorpos][2];
    if(forward){
      colorpos ++;      
    }
    else{
      colorpos --; 
    }
    if (colorpos == 139){
      forward = false; 
    }
    if (colorpos == 0){
      forward = true; 
    }
  }  
}






